「つらみが解決!Rainを使ってCloudFormationをもっと便利に」というテーマで話しました #devio2021
セッションの概要
DevelopersIO 2021 Decadeという弊社オンラインイベントにて、「つらみが解決!Rainを使ってCloudFormationをもっと便利に」というテーマで話しました。
動画
スライド
ソースコード
「個人的Rainのベストプラクティス」のテンプレートやGitHub Actionsのworkflowsのソースコードを共有します。やってみたなどでご利用ください。
system.yml(ネストされたテンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String billingTag: Type: String ### Vpc Parameters vpcCidr: Type: String ### Acm And Route53 Parameters domainName: Type: String hostedZoneId: Type: String ### Ec2 Parameters instanceType: Type: String ### Rds Parameters instanceClass: Type: String masterPassword: Type: String NoEcho: true Resources: ### VPC Vpc: Type: AWS::CloudFormation::Stack Properties: Parameters: env: !Ref env sysName: !Ref sysName billingTag: !Ref billingTag vpcCidr: !Ref vpcCidr Tags: - Key: Name Value: !Sub ${env}-${sysName}-vpc-stack - Key: BillingGroup Value: !Ref billingTag TemplateURL: ./template/vpc.yml ### Iam Iam: Type: AWS::CloudFormation::Stack DependsOn: Vpc Properties: Parameters: env: !Ref env sysName: !Ref sysName Tags: - Key: Name Value: !Sub ${env}-${sysName}-iam-stack - Key: BillingGroup Value: !Ref billingTag TemplateURL: !Rain::S3Http ./template/iam.yml ### Acm Acm: Type: AWS::CloudFormation::Stack Properties: Parameters: env: !Ref env sysName: !Ref sysName billingTag: !Ref billingTag domainName: !Ref domainName hostedZoneId: !Ref hostedZoneId Tags: - Key: Name Value: !Sub ${env}-${sysName}-acm-stack - Key: BillingGroup Value: !Ref billingTag TemplateURL: !Rain::S3Http ./template/acm.yml ### Security Group SecurityGroup: Type: AWS::CloudFormation::Stack DependsOn: Vpc Properties: Parameters: env: !Ref env sysName: !Ref sysName billingTag: !Ref billingTag Tags: - Key: Name Value: !Sub ${env}-${sysName}-securitygroup-stack - Key: BillingGroup Value: !Ref billingTag TemplateURL: !Rain::S3Http ./template/securitygroup.yml ### Rds Rds: Type: AWS::CloudFormation::Stack DependsOn: - SecurityGroup Properties: Parameters: env: !Ref env sysName: !Ref sysName billingTag: !Ref billingTag instanceClass: !Ref instanceClass masterPassword: !Ref masterPassword Tags: - Key: Name Value: !Sub ${env}-${sysName}-rds-stack - Key: BillingGroup Value: !Ref billingTag TemplateURL: !Rain::S3Http ./template/rds.yml ### Ec2 Ec2: Type: AWS::CloudFormation::Stack DependsOn: - SecurityGroup - Iam Properties: Parameters: env: !Ref env sysName: !Ref sysName billingTag: !Ref billingTag instanceType: !Ref instanceType Tags: - Key: Name Value: !Sub ${env}-${sysName}-ec2-stack - Key: BillingGroup Value: !Ref billingTag TemplateURL: !Rain::S3Http ./template/ec2.yml ### ALb Alb: Type: AWS::CloudFormation::Stack DependsOn: - SecurityGroup - Acm - Ec2 Properties: Parameters: env: !Ref env sysName: !Ref sysName billingTag: !Ref billingTag Tags: - Key: Name Value: !Sub ${env}-${sysName}-alb-stacks - Key: BillingGroup Value: !Ref billingTag TemplateURL: !Rain::S3Http ./template/alb.yml ### Route 53 route53: Type: AWS::CloudFormation::Stack DependsOn: - Alb Properties: Parameters: env: !Ref env sysName: !Ref sysName domainName: !Ref domainName hostedZoneId: !Ref hostedZoneId Tags: - Key: Name Value: !Sub ${env}-${sysName}-route53-stack - Key: BillingGroup Value: !Ref billingTag TemplateURL: !Rain::S3Http ./template/route53.yml
vpc.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String billingTag: Type: String ### Vpc Parameters vpcCidr: Type: String Resources: ### VPC MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref vpcCidr Tags: - Key: Name Value: !Sub ${env}-${sysName}-vpc - Key: BillingGroup Value: !Ref billingTag ### Internet Gateway MyInternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub ${env}-${sysName}-igw - Key: BillingGroup Value: !Ref billingTag MyVPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref MyInternetGateway VpcId: !Ref MyVPC ### Public Subnet MyPublicSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 0 - !GetAZs Ref: AWS::Region CidrBlock: !Select [0, !Cidr [!GetAtt MyVPC.CidrBlock, 2, 8]] Tags: - Key: Name Value: !Sub ${env}-${sysName}-public-subnet-1 - Key: BillingGroup Value: !Ref billingTag VpcId: !Ref MyVPC MyPublicSubnet2: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 1 - !GetAZs Ref: AWS::Region CidrBlock: !Select [1, !Cidr [!GetAtt MyVPC.CidrBlock, 2, 8]] Tags: - Key: Name Value: !Sub ${env}-${sysName}-public-subnet-2 - Key: BillingGroup Value: !Ref billingTag VpcId: !Ref MyVPC ### Public Route Table MyPublicRouteTable: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Sub ${env}-${sysName}-public-rtb - Key: BillingGroup Value: !Ref billingTag VpcId: !Ref MyVPC MyPublicRoute: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyInternetGateway RouteTableId: !Ref MyPublicRouteTable MyPublicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MyPublicRouteTable SubnetId: !Ref MyPublicSubnet1 MyPublicSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MyPublicRouteTable SubnetId: !Ref MyPublicSubnet2 ### Private Subnet MyPrivateSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 0 - !GetAZs Ref: AWS::Region CidrBlock: !Select [10, !Cidr [!GetAtt MyVPC.CidrBlock, 12, 8]] Tags: - Key: Name Value: !Sub ${env}-${sysName}-private-subnet-1 - Key: BillingGroup Value: !Ref billingTag VpcId: !Ref MyVPC MyPrivateSubnet2: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 1 - !GetAZs Ref: AWS::Region CidrBlock: !Select [11, !Cidr [!GetAtt MyVPC.CidrBlock, 12, 8]] Tags: - Key: Name Value: !Sub ${env}-${sysName}-private-subnet-2 - Key: BillingGroup Value: !Ref billingTag VpcId: !Ref MyVPC ### Private Route Table MyPrivateRouteTable: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Sub ${env}-${sysName}-private-rtb - Key: BillingGroup Value: !Ref billingTag VpcId: !Ref MyVPC MyPrivateRoute: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyInternetGateway RouteTableId: !Ref MyPrivateRouteTable MyPrivateSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MyPrivateRouteTable SubnetId: !Ref MyPrivateSubnet1 MyPrivateSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MyPrivateRouteTable SubnetId: !Ref MyPrivateSubnet2 ### Outputs Outputs: MyVPC: Value: !Ref MyVPC Export: Name: !Sub ${env}-${sysName}-MyVPC MyPublicSubnet1: Value: !Ref MyPublicSubnet1 Export: Name: !Sub ${env}-${sysName}-MyPublicSubnet1 MyPublicSubnet2: Value: !Ref MyPublicSubnet2 Export: Name: !Sub ${env}-${sysName}-MyPublicSubnet2 MyPrivateSubnet1: Value: !Ref MyPrivateSubnet1 Export: Name: !Sub ${env}-${sysName}-MyPrivateSubnet1 MyPrivateSubnet2: Value: !Ref MyPrivateSubnet2 Export: Name: !Sub ${env}-${sysName}-MyPrivateSubnet2
securitygroup.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String billingTag: Type: String Resources: ### Security Group Alb AlbSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Application load barancer. GroupName: !Sub ${env}-${sysName}-alb-sg VpcId: !ImportValue Fn::Sub: ${env}-${sysName}-MyVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: "-1" FromPort: 0 ToPort: 0 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: !Sub ${env}-${sysName}-alb-sg - Key: BillingGroup Value: !Ref billingTag ### Security Group ec2 ec2SG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: ec2 Instances. GroupName: !Sub ${env}-${sysName}-ec2-sg VpcId: !ImportValue Fn::Sub: ${env}-${sysName}-MyVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !Ref AlbSG SecurityGroupEgress: - IpProtocol: "-1" FromPort: 0 ToPort: 0 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: !Sub ${env}-${sysName}-ec2-sg - Key: BillingGroup Value: !Ref billingTag ### Security Group Rds RdsSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Rds Instances. GroupName: !Sub ${env}-${sysName}-rds-sg VpcId: !ImportValue Fn::Sub: ${env}-${sysName}-MyVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 3306 ToPort: 3306 SourceSecurityGroupId: !Ref ec2SG SecurityGroupEgress: - IpProtocol: "-1" FromPort: 0 ToPort: 0 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: !Sub ${env}-${sysName}-rds-sg - Key: BillingGroup Value: !Ref billingTag ### Outputs Outputs: AlbSG: Value: !Ref AlbSG Export: Name: !Sub ${env}-${sysName}-alb-sg ec2SG: Value: !Ref ec2SG Export: Name: !Sub ${env}-${sysName}-ec2-sg RdsSG: Value: !Ref RdsSG Export: Name: !Sub ${env}-${sysName}-rds-sg
iam.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String Resources: ### ec2 Profilee ec2Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess ec2Profile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref ec2Role Outputs: ec2Profile: Value: !Ref ec2Profile Export: Name: !Sub ${env}-${sysName}-ec2Profile
acm.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String billingTag: Type: String ### Acm And Route53 Parameters domainName: Type: String hostedZoneId: Type: String Resources: ### Alb Acm AlbAcm: Type: AWS::CertificateManager::Certificate Properties: DomainName: !Ref domainName DomainValidationOptions: - DomainName: !Ref domainName HostedZoneId: !Ref hostedZoneId ValidationMethod: DNS Tags: - Key: Name Value: !Sub ${env}-${sysName}-albacm - Key: BillingGroup Value: !Ref billingTag ### Outputs Outputs: AlbAcm: Value: !Ref AlbAcm Export: Name: !Sub ${env}-${sysName}-albacm
ec2.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String billingTag: Type: String ### Ec2 Parameters ec2Ami: Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 instanceType: Type: String Resources: ### ec2 Instance Instance1: Type: AWS::EC2::Instance Properties: ImageId: !Ref ec2Ami InstanceType: !Ref instanceType CreditSpecification: CPUCredits: standard BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true VolumeType: gp3 Iops: 3000 VolumeSize: 8 Encrypted: true SecurityGroupIds: - !ImportValue Fn::Sub: ${env}-${sysName}-ec2-sg SubnetId: !ImportValue Fn::Sub: ${env}-${sysName}-MyPrivateSubnet1 IamInstanceProfile: !ImportValue Fn::Sub: ${env}-${sysName}-ec2Profile Tags: - Key: Name Value: !Sub ${env}-${sysName}-instance1 - Key: BillingGroup Value: !Ref billingTag Instance2: Type: AWS::EC2::Instance Properties: ImageId: !Ref ec2Ami InstanceType: !Ref instanceType CreditSpecification: CPUCredits: standard BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true VolumeType: gp3 Iops: 3000 VolumeSize: 8 Encrypted: true SecurityGroupIds: - !ImportValue Fn::Sub: ${env}-${sysName}-ec2-sg SubnetId: !ImportValue Fn::Sub: ${env}-${sysName}-MyPrivateSubnet2 IamInstanceProfile: !ImportValue Fn::Sub: ${env}-${sysName}-ec2Profile Tags: - Key: Name Value: !Sub ${env}-${sysName}-instance2 - Key: BillingGroup Value: !Ref billingTag Outputs: Instance1: Value: !Ref Instance1 Export: Name: !Sub ${env}-${sysName}-instance1 Instance2: Value: !Ref Instance2 Export: Name: !Sub ${env}-${sysName}-instance2
rds.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String billingTag: Type: String ### Rds Parameters instanceClass: Type: String masterPassword: Type: String NoEcho: true Resources: ### Rds Subnet Group SubnetGroupRds: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: !Sub ${env}-${sysName}-rds-SubnetGroup DBSubnetGroupName: !Sub ${env}-${sysName}-rds-subnetgroup SubnetIds: - !ImportValue Fn::Sub: ${env}-${sysName}-MyPrivateSubnet1 - !ImportValue Fn::Sub: ${env}-${sysName}-MyPrivateSubnet2 Tags: - Key: Name Value: !Sub ${env}-${sysName}-rds-SubnetGroup - Key: BillingGroup Value: !Ref billingTag ### Rds Parameter Group ParameterGroupAurora: Type: AWS::RDS::DBParameterGroup Properties: Description: !Sub ${env}-${sysName}-parametergroup Family: aurora-mysql5.7 ## Rds Cluster Parameter Group clusterParameterGroupAurora: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: !Sub ${env}-${sysName}-cluster-parametergroup Family: aurora-mysql5.7 Parameters: character_set_client: utf8 character_set_connection: utf8 character_set_database: utf8 character_set_results: utf8 character_set_server: utf8 general_log: 1 server_audit_events: CONNECT,QUERY,QUERY_DCL,QUERY_DDL,QUERY_DML,TABLE server_audit_logging: 1 slow_query_log: 1 time_zone: Asia/Tokyo ### Rds Aurora Cluster clusterAurora: Type: AWS::RDS::DBCluster Properties: MasterUsername: root MasterUserPassword: !Ref masterPassword DBClusterIdentifier: !Sub ${env}-${sysName}-cluster Engine: aurora-mysql EngineVersion: 5.7.mysql_aurora.2.10.0 DBClusterParameterGroupName: !Ref clusterParameterGroupAurora DBSubnetGroupName: !Ref SubnetGroupRds DeletionProtection: false Port: 3306 PreferredBackupWindow: 17:00-18:00 BackupRetentionPeriod: 7 PreferredMaintenanceWindow: tue:18:00-tue:19:00 EnableCloudwatchLogsExports: - audit - error - general - slowquery StorageEncrypted: true VpcSecurityGroupIds: - !ImportValue Fn::Sub: ${env}-${sysName}-rds-sg Tags: - Key: Name Value: !Sub ${env}-${sysName}-cluster - Key: BillingGroup Value: !Ref billingTag # Rds Aurora Instance1 DbInstance1: Type: AWS::RDS::DBInstance Properties: DBInstanceIdentifier: !Sub ${env}-${sysName}-db1 DBClusterIdentifier: !Ref clusterAurora DBInstanceClass: !Ref instanceClass Engine: aurora-mysql DBParameterGroupName: !Ref ParameterGroupAurora AutoMinorVersionUpgrade: false PubliclyAccessible: false MonitoringInterval: 0 EnablePerformanceInsights: false Tags: - Key: Name Value: !Sub ${env}-${sysName}-db1 - Key: BillingGroup Value: !Ref billingTag # Rds Aurora Instance2 DbInstance2: Type: AWS::RDS::DBInstance Properties: DBInstanceIdentifier: !Sub ${env}-${sysName}-db2 DBClusterIdentifier: !Ref clusterAurora DBInstanceClass: !Ref instanceClass Engine: aurora-mysql DBParameterGroupName: !Ref ParameterGroupAurora AutoMinorVersionUpgrade: false PubliclyAccessible: false MonitoringInterval: 0 EnablePerformanceInsights: false Tags: - Key: Name Value: !Sub ${env}-${sysName}-db2 - Key: BillingGroup Value: !Ref billingTag
alb.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String billingTag: Type: String Resources: ### Alb Alb: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: IpAddressType: ipv4 Name: !Sub ${env}-${sysName}-alb Scheme: internet-facing SecurityGroups: - !ImportValue Fn::Sub: ${env}-${sysName}-alb-sg Subnets: - !ImportValue Fn::Sub: ${env}-${sysName}-MyPublicSubnet1 - !ImportValue Fn::Sub: ${env}-${sysName}-MyPublicSubnet2 Type: application Tags: - Key: Name Value: !Sub ${env}-${sysName}-api - Key: BillingGroup Value: !Ref billingTag AlbListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: Certificates: - CertificateArn: !ImportValue Fn::Sub: ${env}-${sysName}-albacm DefaultActions: - FixedResponseConfig: ContentType: text/plain MessageBody: Unauthorized Access StatusCode: "403" Type: fixed-response LoadBalancerArn: !Ref Alb Port: 443 Protocol: HTTPS SslPolicy: ELBSecurityPolicy-2016-08 AlbListnerRule1: Type: AWS::ElasticLoadBalancingV2::ListenerRule Properties: Actions: - TargetGroupArn: !Ref TargetGroup Type: forward Conditions: - Field: path-pattern PathPatternConfig: Values: - '*' ListenerArn: !Ref AlbListener Priority: 1 ### Target Group for ec2 Instance TargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: !Sub ${env}-${sysName}-ec2 Port: 80 Protocol: HTTP TargetType: instance Targets: - Id: !ImportValue Fn::Sub: ${env}-${sysName}-instance1 - Id: !ImportValue Fn::Sub: ${env}-${sysName}-instance2 VpcId: !ImportValue Fn::Sub: ${env}-${sysName}-MyVPC Tags: - Key: Name Value: !Sub ${env}-${sysName}-tg - Key: BillingGroup Value: !Ref billingTag ### Outputs Outputs: AlbDomainName: Value: !Join - "" - - dualstack. - !GetAtt Alb.DNSName Export: Name: !Sub ${env}-${sysName}-alb-domain
route53.yml(子テンプレート)
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: ### Common Parameters env: Type: String sysName: Type: String ### Acm And Route53 Parameters domainName: Type: String hostedZoneId: Type: String Resources: ### Alb DNS Record AlbRecordSet: Type: AWS::Route53::RecordSet Properties: Name: !Ref domainName Type: A AliasTarget: HostedZoneId: Z14GRHDCWA56QT DNSName: !ImportValue Fn::Sub: ${env}-${sysName}-alb-domain EvaluateTargetHealth: false HostedZoneId: !Ref hostedZoneId
dev-deploy.yml(GitHub Actions)
name: cfn deploy ### devブランチのpushがトリガー on: push: branches: - dev workflow_dispatch: ### envは環境に応じて修正 jobs: deploy: runs-on: ubuntu-latest permissions: id-token: write contents: read env: ENV: dev SYSNAME: example BILLINGTAG: example CIDR: 10.255.0.0/16 DOMAIN_NAME: dev.example.com HOSTED_ZONE_ID: Z10116024XXXXXXXXXXX INSTANCE_TYPE: t3.micro INSTANCE_CLASS: db.t3.small MASTERPASSWORD: ${{ secrets.MASTERPASSWORD }} steps: - name: setup run: | brew install rain echo "rain -v" rain -v - name: there's still a race condition for now run: sleep 5 ### AWS_ROLE_ARN、AWS_DEFAULT_REGION変数は環境に応じて修正 - name: Configure AWS run: | export AWS_ROLE_ARN=arn:aws:iam::123456789012:role/GithubActionRole export AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/awscreds export AWS_DEFAULT_REGION=ap-northeast-1 echo AWS_WEB_IDENTITY_TOKEN_FILE=$AWS_WEB_IDENTITY_TOKEN_FILE >> $GITHUB_ENV echo AWS_ROLE_ARN=$AWS_ROLE_ARN >> $GITHUB_ENV echo AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION >> $GITHUB_ENV curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL" | jq -r '.value' > $AWS_WEB_IDENTITY_TOKEN_FILE - uses: actions/checkout@v2 with: ref: dev - name: Check the Format of the CloudFormation template. run: | echo Returns an error if not formatted. rain fmt -v ./template/*yml - name: Template deploy. run: | rain deploy -y ./system.yml $ENV-stack --params \ env=$ENV,\ sysName=$SYSNAME,\ billingTag=$BILLINGTAG,\ vpcCidr=$CIDR,\ domainName=$DOMAIN_NAME,\ hostedZoneId=$HOSTED_ZONE_ID,\ instanceType=$INSTANCE_TYPE,\ instanceClass=$INSTANCE_CLASS,\ masterPassword=$MASTERPASSWORD
stg-deploy.yml(GitHub Actions)
name: cfn deploy ### stgブランチのpushがトリガー on: push: branches: - stg workflow_dispatch: ### envは環境に応じて修正 jobs: deploy: runs-on: ubuntu-latest permissions: id-token: write contents: read env: ENV: stg SYSNAME: example BILLINGTAG: example CIDR: 10.254.0.0/16 DOMAIN_NAME: stg.example.com HOSTED_ZONE_ID: Z10116024XXXXXXXXXXX INSTANCE_TYPE: t3.micro INSTANCE_CLASS: db.t3.small MASTERPASSWORD: ${{ secrets.MASTERPASSWORD }} steps: - name: setup run: | brew install rain echo "rain -v" rain -v - name: there's still a race condition for now run: sleep 5 ### AWS_ROLE_ARN、AWS_DEFAULT_REGION変数は環境に応じて修正 - name: Configure AWS run: | export AWS_ROLE_ARN=arn:aws:iam::123456789012:role/GithubActionRole export AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/awscreds export AWS_DEFAULT_REGION=ap-northeast-1 echo AWS_WEB_IDENTITY_TOKEN_FILE=$AWS_WEB_IDENTITY_TOKEN_FILE >> $GITHUB_ENV echo AWS_ROLE_ARN=$AWS_ROLE_ARN >> $GITHUB_ENV echo AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION >> $GITHUB_ENV curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL" | jq -r '.value' > $AWS_WEB_IDENTITY_TOKEN_FILE - uses: actions/checkout@v2 with: ref: stg - name: Check the Format of the CloudFormation template. run: | echo Returns an error if not formatted. rain fmt -v ./template/*yml - name: Template deploy. run: | rain deploy -y ./system.yml $ENV-stack --params \ env=$ENV,\ sysName=$SYSNAME,\ billingTag=$BILLINGTAG,\ vpcCidr=$CIDR,\ domainName=$DOMAIN_NAME,\ hostedZoneId=$HOSTED_ZONE_ID,\ instanceType=$INSTANCE_TYPE,\ instanceClass=$INSTANCE_CLASS,\ masterPassword=$MASTERPASSWORD
prd-deploy.yml(GitHub Actions)
name: cfn deploy ### mainブランチのpushがトリガー on: push: branches: - main workflow_dispatch: ### envは環境に応じて修正 jobs: deploy: runs-on: ubuntu-latest permissions: id-token: write contents: read env: ENV: prd SYSNAME: example BILLINGTAG: example CIDR: 10.0.0.0/16 DOMAIN_NAME: example.com HOSTED_ZONE_ID: Z10116024ZZZZZZZZZZ INSTANCE_TYPE: m5.large INSTANCE_CLASS: db.m5.large MASTERPASSWORD: ${{ secrets.MASTERPASSWORD }} steps: - name: setup run: | brew install rain echo "rain -v" rain -v - name: there's still a race condition for now run: sleep 5 ### AWS_ROLE_ARN、AWS_DEFAULT_REGION変数は環境に応じて修正 - name: Configure AWS run: | export AWS_ROLE_ARN=arn:aws:iam::123456789012:role/GithubActionRole export AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/awscreds export AWS_DEFAULT_REGION=ap-northeast-1 echo AWS_WEB_IDENTITY_TOKEN_FILE=$AWS_WEB_IDENTITY_TOKEN_FILE >> $GITHUB_ENV echo AWS_ROLE_ARN=$AWS_ROLE_ARN >> $GITHUB_ENV echo AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION >> $GITHUB_ENV curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL" | jq -r '.value' > $AWS_WEB_IDENTITY_TOKEN_FILE - uses: actions/checkout@v2 with: ref: main - name: Check the Format of the CloudFormation template. run: | echo Returns an error if not formatted. rain fmt -v ./template/*yml - name: Template deploy. run: | rain deploy -y ./system.yml $ENV-stack --params \ env=$ENV,\ sysName=$SYSNAME,\ billingTag=$BILLINGTAG,\ vpcCidr=$CIDR,\ domainName=$DOMAIN_NAME,\ hostedZoneId=$HOSTED_ZONE_ID,\ instanceType=$INSTANCE_TYPE,\ instanceClass=$INSTANCE_CLASS,\ masterPassword=$MASTERPASSWORD
リンク
rain
GitHub ActionsでAWSの永続的なクレデンシャルを渡すことなくIAM Roleが利用できるようになったようです
※ 当初公開されていたGitHub Actionsが引き受けるIAMロールを作成するCloudFormationテンプレートのOIDCプロバイダURLが変更されました。
変更前:https://vstoken.actions.githubusercontent.com
変更後:https://token.actions.githubusercontent.com
AWS federation comes to GitHub Actions
おわりに
DevelopersIO 2021 Decade では、他にも多数の ビデオセッション が順次公開されています。 また、10/5 〜 10/14 の期間中に ライブセッション も開催されますので、そちらもチェックしていただけると幸いです。